#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char letra = '0';
char* palavra;
//char** texto = 0;
char* pteste;
char* frase;
int nroletras = 0;//funcionalidade modificada pois soh pega de a ate z
int nrofrases = 0;//na aplicacao jah eh incrementado logo no comeco para facilitar as alocacoes, MAS faz sentido pois se entra no while eh sinal q vai haver pelo menos uma frase a mais
int x = 0;
int partitionsize = 5000;
int tamstring;
int j;
int interromperepeat;
int tamstring;
int deslocamento;
int indicefrase;
int indstr;
char letrafrase;
int percorre;
int ehsubstr;
int diferente;
char* subfrase;
int interrompesubstr;
int ascii;
int tamanhodicionario = 1000000;//comentei dicionario para testar mais rapido
int indicedicionario = 0;
char* dicionario;
char* copia;
int base = 0;
int total = 0;
int geradas = 0;

struct tvetorletra{
  char* letra;
  int tamanho;
};

typedef struct tvetorletra vetorletra;

vetorletra* duas;
vetorletra* tres;
vetorletra* quatro;
vetorletra* cinco;

int nropalavrasduas = 0;
int nropalavrastres = 0;
int nropalavrasquatro = 0;
int nropalavrascinco = 0;

int main()
{
    //RAND_MAX = 28;

    FILE* fp = fopen("prhases.txt","rb");
    if(fp == NULL) printf("isso n deveria estar aoarecendo");
    //=============aloca o dicionario e os vetores de palavras de tamanho fixo=============
    dicionario = (char*)malloc( tamanhodicionario*(sizeof(char)) );
    int m = 0;
    duas = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    if( duas == NULL)
      printf("erro na primeira alocacao de duas");
    for( m = 0; m < 26; m++){
      duas[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      duas[m].tamanho = 0;
      if( duas[m].letra == NULL)
        printf("erro na segunda alocacao de duas");
      printf("\n alocando");
    }
    tres = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      tres[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      tres[m].tamanho = 0;
    }
    quatro = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      quatro[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      quatro[m].tamanho = 0;
    }
    cinco = (vetorletra*)malloc( 26*(sizeof(vetorletra)) );
    for( m = 0; m < 26; m++){
      cinco[m].letra = (char*)malloc( 200000*(sizeof(char)) );
      cinco[m].tamanho = 0;
    }
    printf("terminou alocacao");
    //======================================================================================

    //=====filtra arquivo e aloca os vetores de 2,3,4 e 5 porem nao em ordem alfabetica=====
    if( dicionario  == NULL){
      printf("\nnao conseguiu alocar a memoria desejada\n");
    }
    char* pequena = (char*)malloc( 1000*(sizeof(char)) );
    copia = (char*) malloc( (1000)*(sizeof(char)) );
    int lim = 0;
    nroletras = 0;
    int k = 0;
    int kquatro = 0;
    int kcinco = 0;
    int indletra = 0;
    do{//aloca as frases em cada linha da matriz
        fread(&letra,sizeof(char),1,fp);//fica com nroletras sendo essa a quantidade total incluindo o \0
        if( ((letra > 96) && (letra < 123)) || (letra == 44) ){//comi os espacos
          pequena[nroletras] = letra;
          nroletras++;
          if( letra == 44){
            pequena[nroletras - 1] = '\0';
            lim = strlen(pequena);
            if( (lim >  1) && (lim < 6) ){
             if(!procuradicionario(dicionario,pequena,copia,indicedicionario) ){
              adicionanodicionario(dicionario,pequena,&indicedicionario);
              total++;
              indletra = ( ((int) pequena[0] ) - 97 )%26;//pega qual a letra do alfabeto
              if(lim == 2){
                  //colocar dicionario
                  for(k = 0; k < lim + 1; k++,duas[indletra].tamanho++){//rcebe ateh o barra zero
                    duas[indletra].letra[duas[indletra].tamanho]= pequena[k];
                  }
              }
              if(lim == 3){
                  for(k = 0; k < lim + 1; k++,tres[indletra].tamanho++){//rcebe ateh o barra zero
                    tres[indletra].letra[tres[indletra].tamanho]= pequena[k];
                  }
              }
               if(lim == 4){
                  for(k = 0; k < lim + 1; k++,quatro[indletra].tamanho++){//rcebe ateh o barra zero
                    quatro[indletra].letra[quatro[indletra].tamanho]= pequena[k];
                  }
              }
               if(lim == 5){
                  for(k = 0; k < lim + 1; k++,cinco[indletra].tamanho++){//rcebe ateh o barra zero
                    cinco[indletra].letra[cinco[indletra].tamanho]= pequena[k];
                  }
              }
              }
             }
            nroletras = 0;//nroletras zera pois depois de colocar essa de dois deve-se recomecar a pequena string
            }
        }
    }while( ( !feof(fp) ) );
    //========================================================
    for(k=0; k<duas[0].tamanho;k++){
      printf("%c",duas[0].letra[k]);
    }

    //======geracao da string aletoria de mil e passeios======
      //vou usar rand mas devo trocar para drand48_r(3)
      palavra = malloc( (1000)*(sizeof(char)) );// como a frase sempre eh grande e n existe palavra maior q mil entao coloquei esse tamanho arbitrariamente
      char* aleatoria = (char*)malloc( (1000)*(sizeof(char)) );
      char* minialeatoriaduas = (char*)malloc( 3*sizeof(char));
      char* minialeatoriatres = (char*)malloc( 4*sizeof(char));
      char* minialeatoriaquatro = (char*)malloc( 5*sizeof(char));
      char* minialeatoriacinco = (char*)malloc( 6*sizeof(char));
      char* miniletra = (char*)malloc(6*sizeof(char));//nao precisa ser mais q 6 pois a maior string para comparacao eh de tamanho 6
      subfrase = malloc( (1000)*(sizeof(char)) );
      srand ( time(NULL) );
      tamstring = 0;
      indicefrase = 0;
      letrafrase = '0';//inicializacao basica
      base = 0;
      int c = 0;
      indletra = 0;
      int somatotal = 0;


      nropalavrasduas = 0;
      for(k=0; k<26; k++){
        nropalavrasduas = nropalavrasduas + duas[k].tamanho;//nrototal de
      }
      printf("\nnropalavrasduas: %d %d",nropalavrasduas,(nropalavrasduas/3) );
      nropalavrasduas = nropalavrasduas/3;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrasduas > 0){
          base = 0;
          do{
            minialeatoriaduas[0] = aleatoria[base];
            minialeatoriaduas[1] = aleatoria[base + 1];
            minialeatoriaduas[2] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < duas[indletra].tamanho; c = c + 3){//tem q se c = c + 3 pois o anda o vetor
               miniletra[0] = duas[indletra].letra[c];
               miniletra[1] = duas[indletra].letra[c+1];
               miniletra[2] = duas[indletra].letra[c+2];
               if( strcmp(minialeatoriaduas,miniletra) == 0){
                 geradas++;
                 printf("\npalavra encontrada %s", miniletra);
                 duas[indletra].letra[c] = '-';
                 duas[indletra].letra[c+1] = '-';
                 duas[indletra].letra[c+2] = '\0';
                 nropalavrasduas--;
                 c = duas[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrasduas > 0) && (base < 998) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrasduas > 0 );




      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrastres = 0;
      for(k=0; k<26; k++){
        nropalavrastres = nropalavrastres + tres[k].tamanho;//nrototal de
      }
      printf("\nnropalavrastres: %d %d",nropalavrastres,(nropalavrastres/4) );
      nropalavrastres = nropalavrastres/4;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrastres > 0){
          base = 0;
          do{
            minialeatoriatres[0] = aleatoria[base];
            minialeatoriatres[1] = aleatoria[base + 1];
            minialeatoriatres[2] = aleatoria[base + 2];
            minialeatoriatres[3] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < tres[indletra].tamanho; c = c + 4){
               miniletra[0] = tres[indletra].letra[c];
               miniletra[1] = tres[indletra].letra[c+1];
               miniletra[2] = tres[indletra].letra[c+2];
               miniletra[3] = tres[indletra].letra[c+3];
               if( strcmp(minialeatoriatres,miniletra) == 0){
                 geradas++;
                 printf("\npalavra encontrada %s", miniletra);
                 tres[indletra].letra[c] = '-';
                 tres[indletra].letra[c+1] = '-';
                 tres[indletra].letra[c+2] = '-';
                 tres[indletra].letra[c+3] = '\0';
                 nropalavrastres--;
                 c = tres[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrastres > 0) && (base < 997) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrastres > 0 );



      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrasquatro = 0;
      for(k=0; k<26; k++){
        nropalavrasquatro = nropalavrasquatro + quatro[k].tamanho;//nrototal de
      }
      printf("\nnropalavrasquatro: %d %d",nropalavrasquatro,(nropalavrasquatro/5));
      nropalavrasquatro = nropalavrasquatro/5;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrasquatro > 0){
          base = 0;
          do{
            minialeatoriaquatro[0] = aleatoria[base];
            minialeatoriaquatro[1] = aleatoria[base + 1];
            minialeatoriaquatro[2] = aleatoria[base + 2];
            minialeatoriaquatro[3] = aleatoria[base + 3];
            minialeatoriaquatro[4] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < quatro[indletra].tamanho; c = c + 5){
               miniletra[0] = quatro[indletra].letra[c];
               miniletra[1] = quatro[indletra].letra[c+1];
               miniletra[2] = quatro[indletra].letra[c+2];
               miniletra[3] = quatro[indletra].letra[c+3];
               miniletra[4] = quatro[indletra].letra[c+4];
               if( strcmp(minialeatoriaquatro,miniletra) == 0){
                 geradas++;
                 printf("\npalavra encontrada %s com porcentagem %d", miniletra, (nropalavrasquatro/((quatro[indletra].tamanho)/5)) );
                 quatro[indletra].letra[c] = '-';
                 quatro[indletra].letra[c+1] = '-';
                 quatro[indletra].letra[c+2] = '-';
                 quatro[indletra].letra[c+3] = '-';
                 quatro[indletra].letra[c+4] = '\0';
                 nropalavrasquatro--;
                 c = quatro[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrasquatro > 0) && (base < 996) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrasquatro > 0 );






      base = 0;
      c = 0;
      indletra = 0;
      somatotal = 0;

      nropalavrascinco = 0;
      for(k=0; k<26; k++){
        nropalavrascinco = nropalavrascinco + cinco[k].tamanho;//nrototal de
      }
      printf("\nnropalavrascinco: %d %d",nropalavrascinco,(nropalavrascinco/6) );
      nropalavrascinco = nropalavrascinco/6;
      do{
        for(k=0;k<1000;k++){
          ascii = (rand() % 26) + 97;
          aleatoria[k] = (char)ascii;
        }
        if( nropalavrascinco > 0){
          base = 0;
          do{
            minialeatoriacinco[0] = aleatoria[base];
            minialeatoriacinco[1] = aleatoria[base + 1];
            minialeatoriacinco[2] = aleatoria[base + 2];
            minialeatoriacinco[3] = aleatoria[base + 3];
            minialeatoriacinco[4] = aleatoria[base + 4];
            minialeatoriacinco[5] = '\0';
            indletra = ( ((int) aleatoria[base] ) - 97 )%26;
            for(c = 0; c < cinco[indletra].tamanho; c = c + 6){
               miniletra[0] = cinco[indletra].letra[c];
               miniletra[1] = cinco[indletra].letra[c+1];
               miniletra[2] = cinco[indletra].letra[c+2];
               miniletra[3] = cinco[indletra].letra[c+3];
               miniletra[4] = cinco[indletra].letra[c+4];
               miniletra[5] = cinco[indletra].letra[c+5];
               if( strcmp(minialeatoriacinco,miniletra) == 0){
                 geradas++;
                 printf("\npalavra encontrada %s com porcentagem %lf", miniletra, ( ((double)geradas) /(  ( ( double)total)) ) );
                 cinco[indletra].letra[c] = '-';
                 cinco[indletra].letra[c+1] = '-';
                 cinco[indletra].letra[c+2] = '-';
                 cinco[indletra].letra[c+3] = '-';
                 cinco[indletra].letra[c+4] = '-';
                 cinco[indletra].letra[c+5] = '\0';
                 nropalavrascinco--;
                 c = cinco[indletra].tamanho;//acho q eh equivalente a break
               }
            }
            base++;
            //printf(" %d",base);
          }while( (nropalavrascinco > 0) && (base < 995) );//tomar cuidado na hora de replicar com essa linhas e qq otra haver com a base
        }
      }while( nropalavrascinco > 0 );


      /*while( ((indicefrase < strlen(frase)) && ( frase[indicefrase] != ',') ) && ( (frase[indicefrase] != '\n') && ( frase[indicefrase] != '\r') ) ){
        letrafrase = frase[indicefrase];
        subfrase[indstr] = frase[indicefrase];
        indicefrase++;
        indstr++;
      }
      */
      /*
      subfrase[indstr] = '\0';
      indstr = 0;
      indicefrase++;//para pular a virgula ou caso n tenha o if de baixo considera maior ou igual
      interrompesubstr = 0;
      //=================================verificacoes de interrupcao=============================
      if( strlen(subfrase) > 5 ){//ve se a string eh maior q cinco para ver se faz ou n faz
        interrompesubstr = 1;
        //printf("\nnao pegou a palavra da frase \n%s\n",subfrase);
      }else{
        interrompesubstr = procuradicionario(dicionario,subfrase,copia,indicedicionario);
        printf("\nesse ==========>>>>>> %d",interrompesubstr);
      }
      if(  !((subfrase[0] > 96) && (subfrase[0]< 123)) || ( (subfrase[0] == 32)   ) ){//importante, escolher se a primeira letra n pode ser diferente dos asc de letra minuscula, caso contrario sai do repeat, ou colocar pra se a primeira seria \n o q n faria tanto sentido.
        interrompesubstr = 1;
        interromperepeat = 1;
        printf("\ninterrompeu o repeat pois pegou estring vazia ou algo do tipo \n%s=\n",subfrase);
      }
      //=========================================================================================
      while( !interrompesubstr ){//enquanto n tiver uma string q bata com uma palavra nao sai deste trecho
      //printf("\npalavra atual \n%s\n",subfrase);
      if( indicefrase >= strlen(frase) ){
        interromperepeat = 1;
      }
      //ascii = (rand() % 26) + 97;// de 0 a 25 de a a z com o respectivo ascii
      ascii = (rand() % 27) + 97;// de 0 a 25 de a a } pois o no casi de } o if deveria funcionar
      if ( ascii == 123 ){
        ascii = 32;
      }
      palavra[tamstring] = ascii;
      //printf("  char randominco %c",palavra[tamstring]);
      tamstring++;
      palavra[tamstring] = '\0';
      //if( strlen(palavra) > 2){
        //printf("  trecho igual tres %s\n", palavra);
      //}
      ehsubstr = 0;
      diferente = 1;
      percorre = 0;
      while( percorre < (strlen(palavra)) ){
        //printf("percorrendo palavra ");
        if(palavra[percorre] == subfrase[percorre]){
          //printf(" rand correto %c  %c",palavra[percorre], subfrase[percorre]);
          ehsubstr = 1;
          diferente = 0;
        }else{
          //printf("   %c dif %c",palavra[percorre],subfrase[percorre]);
          ehsubstr = 0;
          diferente = 1;
          break;
        }
        percorre++;
      }
      if (diferente){
        tamstring = 0;
      }else{
        if(strlen(palavra) == strlen(subfrase)){
          adicionanodicionario(dicionario,palavra,&indicedicionario);
          printf("\n palavra encontrada %s\n=====",palavra);
          interrompesubstr = 1;
        }
        else{
          //n faz nada pois deixa a string aumentar jah q eh substring mas ainda n bateu com a palavra
        }
      }
      }

      }while( !interromperepeat);
      //=========================================================
      int j = 0;
      printf("\n");
      for(j=0;j<indicedicionario;j++){
        printf("%c",dicionario[j]);
      }
      printf("\n");
      //scanf("%d",&x);
      nroletras = 0;


    printf("Foram lidas %d frases\n",nrofrases);
    */
    fclose(fp);
    return 0;

}

int adicionanodicionario( char* dicionario, char* str, int* indicedicionario){

  int indpalavra = 0;
  for ( indpalavra = 0; indpalavra < strlen(str) + 1; indpalavra++, (*indicedicionario)++){//vai ateh strlen mais um para poder pegar o \0
    dicionario[(*indicedicionario)] = str[indpalavra];
  }//como o for incrementa na ultima iteracao, logo o valor jah sai no local certo
  return 0;

}


int procuradicionario( char* dicionario, char* str, char* copia,int indiceatual){

  int indpalavra = 0;
  int cpyindicedicionario = 0;
  int interrompe  = 0;
  int lim = strlen(dicionario);
  while( (cpyindicedicionario < indiceatual) && (interrompe == 0) ) {//varre o dicionario com o indice de baixo
    indpalavra = 0;
    while (  ((dicionario[cpyindicedicionario] != '\0') && ( cpyindicedicionario < indiceatual)) && (interrompe == 0) ){//como dicionario tem varios \0
      copia[indpalavra] = dicionario[cpyindicedicionario];//copia eh alocado no principal com o mesmo tamanho de uma palavra
      indpalavra++;
      cpyindicedicionario++;
    }
    cpyindicedicionario++;//para pular o \0
    copia[indpalavra] = '\0';
    if( strcmp(copia,str) == 0 ){
      interrompe = 1;
      //printf("\n==__== a palavra %s foi otimizada ==__== %d",str,interrompe);
      return interrompe;
    }
  }
  return interrompe;
}

//nao eh utilizado
int tempalavaras(char* frase){

  int i = 0;
  for(i = 0; i < strlen(frase); i++){
    if( (frase[i] > 96) && (frase[i] <123) ){
      return 1;
    }
  }
  return 0 ;
}





